# 设置编译器最低版本
cmake_minimum_required(VERSION 3.0.2)

# 项目名称
project(cre)

set(CMAKE_CXX_STANDARD 14)

#查找依赖库
find_package(catkin REQUIRED COMPONENTS
        roscpp
        rospy
        std_msgs
        message_generation
        genmsg
        actionlib
        actionlib_msgs
        cv_bridge
        image_transport
        image_geometry
        nav_msgs
        tf
        tf2_geometry_msgs
        tf2_sensor_msgs
        pcl_ros
        dynamic_reconfigure
)

find_package(Threads REQUIRED)
find_package(OpenCV REQUIRED)

file(GLOB GLOG_LIBRARIES /usr/lib/x86_64-linux-gnu/libglog.so)
set(GLOG_INCLUDE_DIRS /usr/include)
message("glog_include_dirs=${GLOG_INCLUDE_DIRS}")

# 自定义消息文件
add_message_files(DIRECTORY msg FILES CreMessage.msg)

# 自定义服务文件
add_service_files(DIRECTORY srv FILES CreServiceMsg.srv)

# 自定义动作库
add_action_files(DIRECTORY action FILES CreAction.action)

# 生成自定义消息宏
generate_messages(DEPENDENCIES actionlib_msgs cre)

# 生成动态配置参数
generate_dynamic_reconfigure_options(cfg/CreTutorials.cfg)

catkin_package(
        INCLUDE_DIRS include
        LIBRARIES cre
        #  CATKIN_DEPENDS roscpp rospy std_msgs
        #  DEPENDS system_lib
        CATKIN_DEPENDS roscpp
        rospy
        std_msgs
        message_runtime
        actionlib
        actionlib_msgs
        image_transport
        cv_bridge
        nav_msgs
        image_geometry
        tf tf2_geometry_msgs
        tf2_sensor_msgs
        pcl_ros
        dynamic_reconfigure
)

# 添加头文件
include_directories(${GLOG_INCLUDE_DIRS})
include_directories(include ${catkin_INCLUDE_DIRS})
include_directories(include ${OpenCV_INCLUDE_DIRS})

## 编译原理
# 编译过程
add_executable(compilation_principles src/robot_cpp_language/compilation_principles.cpp)

## C++基本语法
# 变量和数据类型
add_executable(variables_and_data_types src/robot_cpp_language/variables_and_data_types.cpp)
# 运算符
add_executable(operator_cpp src/robot_cpp_language/operator_cpp.cpp)
# 控制结构
add_executable(control_structure src/robot_cpp_language/control_structure.cpp)
# 函数
add_executable(function_cpp src/robot_cpp_language/function_cpp.cpp)
# 指针
add_executable(pointer src/robot_cpp_language/pointer.cpp)
add_executable(pointer_and_array src/robot_cpp_language/pointer_and_array.cpp)
# 类与对象
add_executable(class_example_car src/robot_cpp_language/class_example_car.cpp)
add_executable(class_example_person src/robot_cpp_language/class_example_person.cpp)
# 类的继承
add_executable(inheritance_animal src/robot_cpp_language/inheritance_animal.cpp)
add_executable(inheritance_shape src/robot_cpp_language/inheritance_shape.cpp)
# 类的多态
add_executable(polymorphic src/robot_cpp_language/polymorphic.cpp)

## C++机器人应用
# vector
add_executable(example_vector src/robot_cpp_language/example_vector.cpp)
# 堆栈和队列
add_executable(example_stack_queue src/robot_cpp_language/example_stack_queue.cpp)
# 关联容器
add_executable(example_associative_container src/robot_cpp_language/example_associative_container.cpp)
# 排序，查找与遍历
add_executable(example_sort_find_traverse src/robot_cpp_language/example_sort_find_traverse.cpp)
# 多线程
add_executable(multithreading src/robot_cpp_language/multithreading.cpp)
target_link_libraries(multithreading Threads::Threads)
# 线程互斥锁
add_executable(thread_mutex src/robot_cpp_language/thread_mutex.cpp)
target_link_libraries(thread_mutex Threads::Threads)

## linux 系统编成
# 使用代码启动一个进程
add_executable(system_start src/linux_system/system_start.cpp)
# 信号
add_executable(system_signal src/linux_system/system_signal.cpp)
# 信号回调
add_executable(system_signal_handler src/linux_system/system_signal_handler.cpp)
# 发送信号
add_executable(system_fork src/linux_system/system_fork.cpp)
# pipe 函数
add_executable(fun_pipe src/linux_system/fun_pipe.cpp)
# fifo 函数
add_executable(fun_fifo src/linux_system/fun_fifo.cpp)
# 线程示例
add_executable(thread_example src/linux_system/thread_example.cpp)
target_link_libraries(thread_example Threads::Threads)
# POSIX 互斥锁
add_executable(pthread_mutex_example src/linux_system/pthread_mutex_example.cpp)
target_link_libraries(pthread_mutex_example Threads::Threads)
# tcp
add_executable(tcp_server src/linux_system/tcp_server.cpp)
add_executable(tcp_client src/linux_system/tcp_client.cpp)
# glog
add_executable(glog_example src/glog_example.cpp)

## ros
# ros node
add_executable(ros_node src/ros_node.cpp)
# 消息发布
add_executable(cre_publisher src/ros/cre_publisher.cpp)
# 消息接受
add_executable(cre_subscriber src/ros/cre_subscriber.cpp)
# ros client
add_executable(cre_client src/ros/cre_client.cpp)
# ros server
add_executable(cre_server src/ros/cre_server.cpp)
# 参数
add_executable(cre_param src/ros/cre_param.cpp)
# action client
add_executable(cre_action_client src/ros/cre_action_client.cpp)
# action server
add_executable(cre_action_server src/ros/cre_action_server.cpp)
# 日志
add_executable(cre_log src/ros/cre_log.cpp)
# 激光雷达
add_executable(cre_scan src/ros/cre_scan.cpp)
# 距离滤波
add_executable(cre_laser_filter src/ros/cre_laser_filter.cpp)
# depth image
add_executable(cre_depth_subscriber src/ros/cre_depth_subscriber.cpp)
# 获取 rgb 图像
add_executable(cre_image_subscriber src/ros/cre_image_subscriber.cpp)
# 深度相机点云
add_executable(cre_point_cloud_subscriber src/ros/cre_point_cloud_subscriber.cpp)
# imu
add_executable(cre_imu_listener src/ros/cre_imu_listener.cpp)
# 距离传感器
add_executable(cre_range_subscriber src/ros/cre_range_subscriber.cpp)
# 移动
add_executable(cre_move_forward_node src/ros/cre_move_forward_node.cpp)
# tf变换
add_executable(cre_tf_listener src/ros/cre_tf_listener.cpp)
# 里程计
add_executable(cre_odom_tracker src/ros/cre_odom_tracker.cpp)
# odom tracker distance
add_executable(cre_odom_tracker_distance src/ros/cre_odom_tracker_distance.cpp)
# laser odom
add_executable(cre_laser_odom src/ros/cre_laser_odom.cpp)
# 时间对齐
add_executable(cre_time_sync_node src/ros/cre_time_sync_node.cpp)
# navigation
add_executable(cre_navigation_node src/ros/cre_navigation_node.cpp)
# planner
add_executable(cre_carrot_planner src/ros/cre_carrot_planner.cpp)
# BUG算法
add_executable(cre_bug src/ros/cre_bug.cpp)
# pid
add_executable(cre_pid_controller_node src/ros/cre_pid_controller_node.cpp)
# 超声避障
add_executable(cre_obstacle_avoidance src/ros/cre_obstacle_avoidance.cpp)
# 点云避障
add_executable(cre_obstacle_detector src/ros/cre_obstacle_detector.cpp)
# 超声
add_executable(cre_ultrasonic_subscriber src/ros/cre_ultrasonic_subscriber.cpp)
# 动态参数
add_executable(cre_dynamic_reconfigure_node src/ros/cre_dynamic_reconfigure_node.cpp)
add_dependencies(cre_dynamic_reconfigure_node ${PROJECT_NAME}_gencfg)
# print time
add_executable(cre_time_printer src/ros/cre_time_printer.cpp)
# 时间回调
add_executable(cre_timer_callback_node src/ros/cre_timer_callback_node.cpp)
# 机械臂
add_executable(cre_moveit_forward_operation src/ros/cre_moveit_forward_operation.cpp)
add_executable(cre_moveit_inverse_operation src/ros/cre_moveit_inverse_operation.cpp)

## 图像
# 图片
add_executable(cre_image src/cv/cre_image.cpp)
# 滤波
add_executable(cre_image_blur src/cv/cre_image_blur.cpp)
# 二值化
add_executable(cre_image_threshold src/cv/cre_image_threshold.cpp)
# 图像缩放
add_executable(cre_image_resize src/cv/cre_image_resize.cpp)
# 图像旋转
add_executable(cre_image_rotated src/cv/cre_image_rotated.cpp)
# 视频
add_executable(cv_video src/cv/cv_video.cpp)

# 链接其他库
target_link_libraries(glog_example ${GLOG_LIBRARIES})

target_link_libraries(ros_node ${catkin_LIBRARIES})
target_link_libraries(cre_publisher ${catkin_LIBRARIES})
target_link_libraries(cre_subscriber ${catkin_LIBRARIES})
target_link_libraries(cre_client ${catkin_LIBRARIES})
target_link_libraries(cre_server ${catkin_LIBRARIES})
target_link_libraries(cre_param ${catkin_LIBRARIES})
target_link_libraries(cre_action_client ${catkin_LIBRARIES})
target_link_libraries(cre_action_server ${catkin_LIBRARIES})
target_link_libraries(cre_log ${catkin_LIBRARIES})
target_link_libraries(cre_scan ${catkin_LIBRARIES})
target_link_libraries(cre_laser_filter ${catkin_LIBRARIES})
target_link_libraries(cre_depth_subscriber ${OpenCV_LIBRARIES} ${catkin_LIBRARIES})
target_link_libraries(cre_image_subscriber ${OpenCV_LIBRARIES} ${catkin_LIBRARIES})
target_link_libraries(cre_point_cloud_subscriber ${catkin_LIBRARIES})
target_link_libraries(cre_imu_listener ${catkin_LIBRARIES})
target_link_libraries(cre_range_subscriber ${catkin_LIBRARIES})
target_link_libraries(cre_move_forward_node ${catkin_LIBRARIES})
target_link_libraries(cre_tf_listener ${catkin_LIBRARIES})
target_link_libraries(cre_odom_tracker ${catkin_LIBRARIES})
target_link_libraries(cre_odom_tracker_distance ${catkin_LIBRARIES})
target_link_libraries(cre_laser_odom ${catkin_LIBRARIES})
target_link_libraries(cre_time_sync_node ${catkin_LIBRARIES})
target_link_libraries(cre_navigation_node ${catkin_LIBRARIES})
target_link_libraries(cre_carrot_planner ${catkin_LIBRARIES})
target_link_libraries(cre_bug ${catkin_LIBRARIES})
target_link_libraries(cre_pid_controller_node ${catkin_LIBRARIES})
target_link_libraries(cre_obstacle_avoidance ${catkin_LIBRARIES})
target_link_libraries(cre_obstacle_detector ${catkin_LIBRARIES})
target_link_libraries(cre_ultrasonic_subscriber ${catkin_LIBRARIES})
target_link_libraries(cre_dynamic_reconfigure_node ${catkin_LIBRARIES})
target_link_libraries(cre_time_printer ${catkin_LIBRARIES})
target_link_libraries(cre_timer_callback_node ${catkin_LIBRARIES})
target_link_libraries(cre_moveit_forward_operation ${catkin_LIBRARIES})
target_link_libraries(cre_moveit_inverse_operation ${catkin_LIBRARIES})

target_link_libraries(cre_image ${catkin_LIBRARIES})
target_link_libraries(cre_image_blur ${catkin_LIBRARIES})
target_link_libraries(cre_image_threshold ${catkin_LIBRARIES})
target_link_libraries(cre_image_resize ${catkin_LIBRARIES})
target_link_libraries(cre_image_rotated ${catkin_LIBRARIES})
target_link_libraries(cv_video ${catkin_LIBRARIES})

# 安装目标文件和其他文件
install(PROGRAMS
        DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)

install(TARGETS ros_node
        RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)

install(DIRECTORY include/
        DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
        FILES_MATCHING PATTERN "*.h"
        PATTERN ".svn" EXCLUDE
)

set(other_dir
        params
        scripts
)

foreach (_dir ${other_dir})
    install(DIRECTORY ${_dir}/
            DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}/${_dir})
endforeach ()
